import { DeleteFilled, EditFilled } from "@ant-design/icons"
import { catalog } from "@mall/api-services"
import { Button, Col, Divider, Input, Row } from "antd"
import * as _ from "lodash"
import * as React from "react"
import { useState } from "react"
import classes from "./product-options.module.scss"

interface ProductOptionValueProps {
  value: catalog.ProductOptionValue;
  onDelete?: (value: catalog.ProductOptionValue) => void;
  onChange?: (value: catalog.ProductOptionValue) => void;
  editable?: boolean;
}

function ProductOptionValue(props: ProductOptionValueProps) {
  const [label, setLabel] = useState(props.value.label)
  const [editable, setEditable] = useState(props.editable)

  function onChangeValue(value: string) {
    if (_.isFunction(props.onChange)) {
      props.onChange(_.assign(new catalog.ProductOptionValue(), props.value, { value }))
    }
    setEditable(false)
  }

  return (
    <>
      {!editable && <div className={classes.optionValue}>
        <span className={classes.optionValueText}>{label}</span>
        <EditFilled onClick={(e: React.MouseEvent<HTMLElement>) => {
          e.stopPropagation()
          setEditable(!editable)
        }}/>
        <Divider type="vertical"/>
        <DeleteFilled onClick={(e: React.MouseEvent<HTMLElement>) => {
          e.stopPropagation()
          if (_.isFunction(props.onDelete)) {
            props.onDelete(_.assign(new catalog.ProductOptionValue(), props.value, { label }))
          }
        }}/>
      </div>}
      {editable &&
      <Input.Search
        className={classes.optionValueInput}
        placeholder="请输入选项值"
        enterButton="确定"
        value={label}
        onChange={e => setLabel(e.target.value)}
        onSearch={onChangeValue}/>}
    </>
  )
}

interface ProductOptionProps {
  option: catalog.ProductOption;
  onChange?: (option: catalog.ProductOption) => void;
  onDelete?: (value: catalog.ProductOption) => void;
}

function ProductOption(props: ProductOptionProps) {
  const [addNewValue, setAddNewValue] = useState("")
  const { option } = props
  const { values } = option


  function onAddValue(label: string) {
    if (!_.isEmpty(label)) {
      setAddNewValue("")
      const newValue = new catalog.ProductOptionValue()
      newValue.label = label
      onChangeValues([...option.values, newValue])
    }
  }

  function onChangeValues(values: catalog.ProductOptionValue[]) {
    option.values = values
    if (_.isFunction(props.onChange)) {
      props.onChange(option)
    }
  }

  function onChangeName(name: string) {
    if (!_.isEqual(name, option.name)) {
      option.name = name
      if (_.isFunction(props.onChange)) {
        props.onChange(option)
      }
    }
  }

  function onDeleteValue(value: catalog.ProductOptionValue) {
    onChangeValues(_.filter(values, aValue => aValue.label !== value.label))
  }

  function onDelete(value: catalog.ProductOption) {
    if (_.isFunction(props.onDelete)) {
      props.onDelete(value)
    }
  }

  return (
    <>
      <Row justify="space-between" align="middle" className={classes.optionName}>
        <Col>
          <Input defaultValue={option.name} onBlur={e => onChangeName(e.currentTarget.value)}
                 onPressEnter={e => onChangeName(e.currentTarget.value)}/>
        </Col>
        <Col>
          <Button type="link" onClick={() => {
            if (_.isFunction(onDelete)) {
              onDelete(option)
            }
          }}>删除选项</Button>
        </Col>
      </Row>
      <div className={classes.optionValues}>
        {_.map(values, (value, index) =>
          <ProductOptionValue
            key={value.label + index}
            value={value}
            editable={_.isUndefined(value.label)}
            onChange={value => {
              values[index] = value
              onChangeValues([...values])
            }}
            onDelete={onDeleteValue}/>)
        }
      </div>
      <Row gutter={[0, 16]}>
        <Col span={12}>
          <Input.Search
            placeholder="请输入选项值"
            enterButton="添加"
            value={addNewValue}
            onChange={e => setAddNewValue(e.target.value)}
            onSearch={onAddValue}/>
        </Col>
      </Row>

    </>
  )
}

interface ProductOptionsProps {
  options: catalog.ProductOption[];
  onChange?: (options: catalog.ProductOption[]) => void;
}

export default function ProductOptions(props: ProductOptionsProps) {
  const { onChange, options } = props

  function onAddOption() {
    const newOption = new catalog.ProductOption()
    newOption.name = ""
    invokeOnChange([...options, newOption])
  }

  function onDeleteOption(option: catalog.ProductOption) {
    invokeOnChange(_.filter(options, aOption => aOption.name !== option.name))
  }

  function invokeOnChange(newOptions: catalog.ProductOption[]) {
    if (_.isFunction(onChange)) {
      onChange(newOptions)
    }
  }

  return (
    <div className={classes.productOptions}>
      {_.map(options, (option, index) =>
        <ProductOption key={option.name + index}
                       option={option}
                       onChange={value => {
                         options[index] = value
                         invokeOnChange([...options])
                       }}
                       onDelete={onDeleteOption}/>)
      }
      <div className={classes.optionActions}>
        <Button onClick={onAddOption}>添加不同选项</Button>
        <Button type="link">自定义排序</Button>
      </div>
    </div>)
}
